home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Kernel / Em / timing.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-17  |  8.9 KB  |  290 lines

  1.  
  2. /* Copyright 1986 Eric Jul.  May not be used for any purpose without    */
  3. /* written permission from the author.                            */
  4.  
  5. /* Various timing routines                                              */
  6. #include <stdio.h>
  7. #include <sys/time.h>
  8.  
  9. #include "Kernel/h/assert.h"
  10. #include "Kernel/h/system.h"
  11. #include "Kernel/h/macros.h"f
  12. #include "Kernel/h/errMsgs.h"
  13. #include "Kernel/h/mmCodes.h"
  14. #include "Kernel/h/emTypes.h"
  15. #include "Kernel/h/timerTypes.h"
  16. #include "Kernel/h/kmdTypes.h"
  17. #include "Kernel/h/kEvents.h"
  18. #include "Kernel/h/emCodes.h"
  19. #include "Kernel/h/mmMsgTypes.h"
  20. #include "Kernel/h/lmTypes.h"
  21. #include "Kernel/h/emkDefs.h"
  22. #include "Kernel/h/lmCodes.h"
  23. #include "Kernel/h/hotsTypes.h"
  24. #include "Kernel/h/map.h"
  25. #include "Kernel/h/timeops.h"
  26. #include "Kernel/h/utils.h"
  27.  
  28. /************************************************************************/
  29.  
  30. int     vTPingDataSize = 4; /* size in bytes of buffer to send */
  31. int     vTPingCount = 1;    /* loop count */
  32. int     vTSleep = 4;        /* Seconds to sleep before timing */
  33. int     vTUseRawSend = 0;   /* Use MM subnet type SNRAWMSG ? */
  34. int     vTLMFillBuf = 0;    /* Should the buffer be filled ? */
  35.  
  36. int     pingCount, thePingId, theLNN;
  37. int     nextPingTimingId = 1;
  38. struct timeval theTime1, theTime2, diff;
  39.  
  40. /************************************************************************/
  41. /*      TDoPing                                                         */
  42. /************************************************************************/
  43.  
  44. void TDoPing()
  45. /* Send out another ping msg or complete the timing.*/
  46. {
  47.     register PingTimingReqItemPtr pingPtr;
  48.     EmMsgPtr                pingMsg;
  49.     int                     size = sizeof(MessageHeader)+sizeof(PingTimingReqItem);
  50.     KKStatus                kstat;
  51.  
  52.     if (pingCount > 0) {
  53.     kstat = MMAllocateMsg(size, (MessagePtr *)&pingMsg);
  54.     assert(mSUCCESS(kstat));
  55.     pingPtr = (PingTimingReqItemPtr) &pingMsg->itemHdr;
  56.     pingPtr->hdr.itemTag = PingTimingITag;
  57.     pingPtr->hdr.size = sizeof(PingTimingReqItem);
  58.     pingPtr->reqId = thePingId;
  59.     pingPtr->pingLNN = GetLNN();
  60.     MMBuildMsg((MessagePtr)pingMsg, KMSG_EmKernel, EMKM_PingTimedReq,
  61.       theLNN, (unsigned)size);
  62.     kstat = vTUseRawSend ? MMSendRawMsg((MessagePtr) pingMsg) :
  63.         MMSendMsg((MessagePtr) pingMsg);
  64.     if ( !mSUCCESS(kstat) ) {
  65.         ErrMsg("Could not send ping msg, status 0x%05x\n", kstat);
  66.         pingCount = 0;
  67.         return;
  68.     }
  69.     MMDeallocateMsg((MessagePtr) pingMsg);
  70.     pingCount--;
  71.     } else {
  72.     xgettime(&theTime2);
  73.     timeSub(diff, theTime2, theTime1);
  74.     printf ("TPing %d loops in %2d.%06d seconds\n", vTPingCount,
  75.         diff.tv_sec, diff.tv_usec);
  76.     printf ("time per loop: %.3f microseconds\n",
  77.         (diff.tv_sec * 1.0e6 + diff.tv_usec) / vTPingCount);
  78.     }
  79. }
  80.  
  81. HResult PingTimingReqHandler(fMsg)
  82. EmMsgPtr            fMsg;
  83. /* Incoming msg handler for Ping Timing Req; returns a pong msg */
  84. {
  85.     PingTimingReqItemPtr  pingPtr;
  86.     PongTimingReqItemPtr  pongPtr;
  87.     EmMsgPtr        replyPtr;
  88.     int             size = sizeof(MessageHeader) + sizeof(PingTimingReqItem);
  89.     KKStatus        kstat;
  90.  
  91.     pingPtr = (PingTimingReqItemPtr) &(fMsg->itemHdr);
  92.     
  93.     if (pingPtr->hdr.itemTag != PingTimingITag) {
  94.     ErrMsg("PingTimingReq: Bad item tag = %s\n",
  95.         PPITag(pingPtr->hdr.itemTag));
  96.     MMDeallocateMsg((MessagePtr) fMsg);
  97.     return;
  98.     }
  99.     DebugMsg(2, "PingTimingReq from LNN %d, reqId %d replying ...\n",
  100.     pingPtr->pingLNN, pingPtr->reqId);
  101.     kstat = MMAllocateMsg(size, (MessagePtr *)&replyPtr);
  102.     assert(mSUCCESS(kstat));
  103.     pongPtr = (PongTimingReqItemPtr) &(replyPtr->itemHdr);
  104.     pongPtr->hdr.itemTag = PongTimingITag;
  105.     pongPtr->hdr.size = sizeof(PongTimingReqItem);
  106.     pongPtr->reqId = pingPtr->reqId;
  107.     pongPtr->pongLNN = GetLNN();
  108.     MMBuildMsg((MessagePtr)replyPtr, KMSG_EmKernel, EMKM_PongTimedReq,
  109.       pingPtr->pingLNN, (unsigned)size);
  110.     kstat = vTUseRawSend ? MMSendRawMsg((MessagePtr) replyPtr) :
  111.     MMSendMsg((MessagePtr) replyPtr);
  112.     if ( !mSUCCESS(kstat) ) {
  113.     DebugMsg(1, "Could not send pong msg, status 0x%05x\n", kstat);
  114.     PutEdenMsg((int)kstat, (FILE *)NULL, (char **)0);
  115.     }
  116.     MMDeallocateMsg((MessagePtr) fMsg);
  117.     MMDeallocateMsg((MessagePtr) replyPtr);
  118. }
  119.  
  120. HResult PongTimingReqHandler(fMsg)
  121. EmMsgPtr            fMsg;
  122. {
  123.     PongTimingReqItemPtr  pongPtr = (PongTimingReqItemPtr) &fMsg->itemHdr;
  124.  
  125.     if (pongPtr->hdr.itemTag != PongTimingITag) {
  126.     DebugMsg(1, "PongTimingReq: Bad item tag = %d\n", pongPtr->hdr.itemTag);
  127.     MMDeallocateMsg((MessagePtr) fMsg);
  128.     return;
  129.     }
  130.     DebugMsg(1, "PongTimingReply recieved from LNN %d, reqId %d\n",
  131.         pongPtr->pongLNN, pongPtr->reqId);
  132.     MMDeallocateMsg((MessagePtr) fMsg);
  133.     
  134.     /* Let TDoPing complete the timing */
  135.     TDoPing();
  136. }
  137.  
  138. HResult TStartPing()
  139. /* Scheduled to run by TPingTiming */
  140. {
  141.     xgettime(&theTime1);
  142.     TDoPing();
  143. }
  144.  
  145. /* Snapshot */
  146. void TPingTiming(fLNN)
  147. int fLNN;
  148. {
  149.   HOTSRecord *HOTSPtr;
  150.  
  151.   KMDPrint("TPingTiming, sending %d ping%s to LNN %d, %s\n", vTPingCount,
  152.        mPLURAL(vTPingCount), fLNN, vTUseRawSend?"RAW":"flow-controlled");
  153.   if (!mSUCCESS(HOTSSearchPtr(fLNN, &HOTSPtr)) ||
  154.       ((HOTSPtr->NodeStat != Alive) && (HOTSPtr->NodeStat != Booting)) ) {
  155.     KMDPrint("Node %d not alive\n", fLNN);
  156.     return;
  157.   }
  158.   theLNN = fLNN;
  159.   thePingId = nextPingTimingId++;
  160.   pingCount = vTPingCount;
  161.   MMSetTimer((unsigned)vTSleep, (HandlerPtr)TStartPing, 0, (TimerId *)0);
  162. }
  163.  
  164. /************************************************************************/
  165. /*      TLMPingTiming-pong message protocol:                            */
  166. /*      PingTiming messages can be sent kernel-kernel at anytime.       */
  167. /*      The receiving kernel merely responds with a pong message.       */
  168. /*      Usefullness: For timing LM messages                             */
  169. /************************************************************************/
  170.  
  171. /* Read a LM msg and send back a LM msg of the same size */
  172. HResult TLMPingTimingReqHandler(fHandle)
  173. LMHandle              fHandle;
  174. {
  175.   LMHandle        myHandle = fHandle;
  176.   int             length, i, sum, lnn;
  177.   int             buf[2000];
  178.     
  179.   lnn = fHandle->mmMsgHdr.MsgSrc;
  180.   sum = 0;
  181.     
  182.   do {
  183.     length = 2000 * sizeof(int);
  184.     LMGetData(&myHandle, &buf[0], &length);
  185.     if (length >0) {
  186.       sum += length;
  187.     }
  188.   } while (length > 0);
  189.   LMClose(&myHandle);
  190.   LMStartMsg(&myHandle, KMSG_EmKernel, EMKM_LMPongTimedReq, lnn);
  191.   if (vTLMFillBuf) {
  192.     for (i = 0; i < sum; i += sizeof(int)) {
  193.       LMPutData(&myHandle, &i, sizeof(int));
  194.     }
  195.   } else {
  196.     LMPutData(&myHandle, (int *) 0, sum);
  197.   }
  198.   LMSendMsg(&myHandle);
  199. }
  200.  
  201. /* Forward */ void TLMDoPing();
  202.  
  203. /* Read a LM msg and continue timing */
  204. HResult TLMPongTimingReqHandler(fHandle)
  205. LMHandle fHandle;
  206. {
  207.   LMHandle myHandle = fHandle;
  208.   int      length;
  209.   int      buf[2000];
  210.     
  211.   do {
  212.     length = 2000* sizeof(int);
  213.     LMGetData(&myHandle, &buf[0], &length);
  214.   } while (length > 0);
  215.   LMClose(&myHandle);
  216.   pingCount--;
  217.   TLMDoPing();
  218. }
  219.  
  220. void TLMDoPing()
  221. {
  222.   LMHandle myHandle;
  223.   int      i;
  224.     
  225.   if(pingCount > 0) {
  226.     LMStartMsg(&myHandle, KMSG_EmKernel, EMKM_LMPingTimedReq, theLNN);
  227.     if (vTLMFillBuf)
  228.       for (i = 0; i < vTPingDataSize; i += sizeof(int)) {
  229.     LMPutData(&myHandle, &i, sizeof(int));
  230.       } else LMPutData(&myHandle, (int *) 0, vTPingDataSize);
  231.     LMSendMsg(&myHandle);
  232.   } else {
  233.     xgettime(&theTime2);
  234.     timeSub(diff, theTime2, theTime1);
  235.     printf ("TLMPing %d bytes, %d loops in %2d.%06d seconds\n",
  236.         vTPingDataSize, vTPingCount, diff.tv_sec, diff.tv_usec);
  237.     printf ("time per loop: %.3f microseconds\n",
  238.         (diff.tv_sec * 1.0e6 + diff.tv_usec) / vTPingCount);
  239.   }
  240. }
  241.  
  242. HResult TLMStartPing()
  243. /* Scheduled to run by TLMPingTiming */
  244. {
  245.   xgettime(&theTime1);
  246.   TLMDoPing();
  247. }
  248.  
  249. /* Snapshot */
  250. void TLMPingTiming(fLNN)
  251. int fLNN;
  252. {
  253.   HOTSRecord *HOTSPtr;
  254.  
  255.   KMDPrint("TLMPingTiming to LNN %d, size = %d, count = %d\n", fLNN,
  256.        vTPingDataSize, vTPingCount);
  257.   KMDPrint("Start timing in %d seconds; output to kernel stdout\n",
  258.        vTSleep);
  259.   KMDPrint("Use ChangeVar snapshot to modify parameters %s\n",
  260.        "vTPingDataSize and vTPingCount");
  261.     
  262.   if (!mSUCCESS(HOTSSearchPtr(fLNN, &HOTSPtr)) ||
  263.       ((HOTSPtr->NodeStat != Alive) && (HOTSPtr->NodeStat != Booting)) ) {
  264.     KMDPrint("Node %d not alive\n", fLNN);
  265.     return;
  266.   }
  267.   theLNN = fLNN;
  268.   thePingId = nextPingTimingId++;
  269.   pingCount = vTPingCount;
  270.   MMSetTimer((unsigned)vTSleep, (HandlerPtr)TLMStartPing, 0, (TimerId *)0);
  271. }
  272.  
  273. /************************************************************************/
  274. void TimingInit()
  275. /* Called at kernel boot time */
  276. {
  277.   KMDSetSnap(TPingTiming);
  278.   KMDSetSnap(TLMPingTiming);
  279.   KMDSetVar(vTPingDataSize);
  280.   MMDefineMsgHandler(KMSG_EmKernel,EMKM_PingTimedReq,
  281.     (HandlerPtr)PingTimingReqHandler, (HandlerPtr *)NULL);
  282.   MMDefineMsgHandler(KMSG_EmKernel, EMKM_PongTimedReq,
  283.     (HandlerPtr)PongTimingReqHandler, (HandlerPtr *)NULL);
  284.   MMDefineMsgHandler(KMSG_EmKernel, EMKM_LMPingTimedReq,
  285.     (HandlerPtr)TLMPingTimingReqHandler, (HandlerPtr *)NULL);
  286.   MMDefineMsgHandler(KMSG_EmKernel, EMKM_LMPongTimedReq,
  287.     (HandlerPtr)TLMPongTimingReqHandler, (HandlerPtr *)NULL);
  288. }
  289.  
  290.